package com.nineshadow.games.netty.socket;

import com.nineshadow.games.netty.message.MessageSend;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 *
 * </p>
 *
 * @author bingjun zhang
 * @since 2018/7/13
 */

@Slf4j
@Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {


    /**
     * 失败计数器：未收到client端发送的ping请求
     */
    private int unRecPingTimes = 0;


    /**
     * 连接事件，服务器的协议(自定义协议管理器)连接到对应的通道中然后触发channelActive事件
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端与服务端连接开启：" + ctx.channel().remoteAddress().toString());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端与服务端连接关闭：{}" , ctx.channel().remoteAddress().toString());
        try {

            log.info("关闭 sessionId:{}",ctx.channel().id().asLongText());
//            HallServer.offline(ctx);
        } catch (Exception e) {
            log.error("断线操作异常",e);
        }
        // 关闭，等待重连
        ctx.channel().close();
    }

    /**
     * 读取客户端发送过来的数据
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        MessageSend.sendMessage(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("异常 sessionId:" + ctx.channel().id().asLongText());
        log.error("客户端与服务端出现异常连接关闭：", cause);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //客户端与服务端空闲状态
        if (evt instanceof IdleStateEvent) {
           unRecPingTimes = MessageSend.TimeIdleStateEvent(ctx, evt, unRecPingTimes);
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }


}
